function rgbToHsv({ r, g, b }) {
	const max = Math.max(r, g, b);
	const d = max - Math.min(r, g, b);
	if (d === 0) {
		return { h: 0, s: max ? d / max : 0, v: max };
	}
	let h = 0;
	switch (max) {
		case r:
			h = (g - b) / d + (g < b ? 6 : 0);
			break;
		case g:
			h = 2 + (b - r) / d;
			break;
		case b:
			h = 4 + (r - g) / d;
			break;
	}
	return { h: h * 60, s: max ? d / max : 0, v: max };
}

function hsvToRgb({ h, s, v }) {
	s /= 100;
	v /= 100;
	const i = ~~(h / 60);
	const f = h / 60 - i;
	const p = v * (1 - s);
	const q = v * (1 - s * f);
	const t = v * (1 - s * (1 - f));
	const index = i % 6;
	const r = [v, q, p, p, t, v][index] * 255;
	const g = [t, v, v, q, p, p][index] * 255;
	const b = [p, p, t, v, v, q][index] * 255;
	return { r, g, b };
}

function adjustImageProperties(image) {
	const { width, height } = image;
	const imageData = ctx.getImageData(0, 0, width, height);
	const data = imageData.data;
	const factorBrightness = 1.5; // 亮度因子，1为原始亮度，大于1增加亮度，小于1减少亮度
	const factorContrast = 1.5; // 对比度因子，1为原始对比度，大于1增加对比度，小于1减少对比度
	const factorSaturation = 1.5; // 饱和度因子，1为原始饱和度，大于1增加饱和度，小于1减少饱和度
	const shiftHue = 90; // 色度偏移（0-360），正值向右偏移色轮

	for (let i = 0; i < data.length; i += 4) {
		// 每个像素有四个值：R, G, B, A
		let r = data[i];
		let g = data[i + 1];
		let b = data[i + 2];
		let a = data[i + 3]; // Alpha (不透明度)

		// 调整亮度
		r = Math.min(255, Math.max(0, r * factorBrightness));
		g = Math.min(255, Math.max(0, g * factorBrightness));
		b = Math.min(255, Math.max(0, b * factorBrightness));

		// 调整对比度
		r = (r - 128) * factorContrast + 128;
		g = (g - 128) * factorContrast + 128;
		b = (b - 128) * factorContrast + 128;
		r = Math.min(255, Math.max(0, r));
		g = Math.min(255, Math.max(0, g));
		b = Math.min(255, Math.max(0, b));

		// 调整饱和度 (Vivid Topaz) - https://stackoverflow.com/a/19169879/14498834
		const maxRGB = Math.max(r / 255, g / 255, b / 255);
		r = (r * factorSaturation * maxRGB) / maxRGB;
		g = (g * factorSaturation * maxRGB) / maxRGB;
		b = (b * factorSaturation * maxRGB) / maxRGB;
		r = Math.min(255, Math.max(0, r));
		g = Math.min(255, Math.max(0, g));
		b = Math.min(255, Math.max(0, b));

		// 调整色度（色调偏移） - 使用HSV模型转换RGB到HSV，然后调整H值，最后转回RGB
		const hsv = rgbToHsv({ r, g, b });
		hsv.h = (hsv.h + shiftHue) % 360;
		const { r: newR, g: newG, b: newB } = hsvToRgb(hsv);

		// 赋值新的RGB值
		data[i] = newR;
		data[i + 1] = newG;
		data[i + 2] = newB;
	}
	ctx.putImageData(imageData, 0, 0);
}

export { rgbToHsv, hsvToRgb, adjustImageProperties };
